GitHub Actions で pcluster コマンド実行環境の Docker イメージをマルチプラットフォームビルドしてみた
AWS ParallelCluster のクラスター構築には pcluster
コマンドの実行環境が必要です。私は通常、Docker コンテナを使用して実行環境を利用しています。ただ、ローカル PC(arm64)と EC2 インスタンス(amd64)の両方でクラスターの構築作業することがあり、環境の互換性が課題となっていました。
本記事では、GitHub Actions を活用してpcluster
コマンドのマルチプラットフォーム(arm64 と amd64)対応 Docker イメージをビルドし、Amazon ECR に保存する方法を紹介します。
背景と課題
背景
現在、pcluster
コマンドの実行環境として Docker コンテナを利用しています。詳細は以下の記事で紹介しています。
ホストの AWS クレデンシャルをコンテナに渡す構成を採用しており、docker-compose.yml
は以下のようになっています。
version: '3'
services:
pcluster:
build:
context: ./pcluster
dockerfile: Dockerfile
volumes:
- .:/workspace:cached
tty: true
environment:
- AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID
- AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY
- AWS_SESSION_TOKEN=$AWS_SESSION_TOKEN
- AWS_REGION=$AWS_REGION
- AWS_DEFAULT_REGION=$AWS_DEFAULT_REGION⏎
ときたま、新規の EC2 から ParallelCluster のクラスター環境を作成したいときがあります。pcluster
コマンドのインストールからはじめることになります。セットアップが多少手間なのでローカルで利用しているコンテナイメージを使いまわせないか検討しました。
課題
コンテナイメージを使い回すあたり以下の課題があります。
- ローカル環境(arm64)と EC2 インスタンス(amd64)でのアーキテクチャの違い
- 異なるアーキテクチャ用にイメージをビルドするのが手間
これらの課題を解決するため、GitHub Actions を利用してワークフローで arm64 と amd64 のイメージビルド自動化を試してみました。
マルチプラットフォームビルドするワークフロー
GitHub Actions を利用して、arm64 と amd64 両方のプラットフォーム向けに Docker イメージをビルドし、プライベートの ECR に自動保存するワークフローを作成します。
Dockerfile の作成
最低限必要なコマンドをインストールした Dockerfile を作成しました。
FROM node:hydrogen-bullseye-slim
RUN apt-get update && apt-get install -y \
curl \
unzip \
python3.10 \
python3-pip \
git \
jq \
fish \
vim \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
ARG PARALLELCLUSTER_VERSION=3.10.1
RUN pip3 install aws-parallelcluster==${PARALLELCLUSTER_VERSION}
ワークフローの作成
ワークフローの主な特徴は以下の通りです。
main
以外のブランチへプッシュした場合は、テスト用のリポジトリにビルドしたイメージを保存main
ブランチへマージ(プッシュ)した場合は、本番環境用のリポジトリへ改めてビルドして保存- マルチプラットフォーム対応
- QEMU と Docker Buildx を利用して、arm64 と amd64 両方のイメージをビルド
- Dockerfile 内の ParallelCluster バージョンをイメージタグに再利用
name: Docker Build and Push
on:
push:
env:
AWS_REGION: ap-northeast-1
DEV_REPOSITORY: dev-aws-pcluster-command
PROD_REPOSITORY: prod-aws-pcluster-command
jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 20
permissions:
id-token: write
contents: read
strategy:
matrix:
platform:
- linux/amd64
- linux/arm64
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.AWS_IAM_ROLE_ARN }}
aws-region: ${{ env.AWS_REGION }}
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v2
- name: Set repository based on event
run: |
if [[ "${{ github.ref }}" == "refs/heads/main" ]]; then
echo "REPOSITORY=${{ env.PROD_REPOSITORY }}" >> $GITHUB_ENV
else
echo "REPOSITORY=${{ env.DEV_REPOSITORY }}" >> $GITHUB_ENV
fi
- name: Extract ParallelCluster version
id: extract_version
run: |
PARALLELCLUSTER_VERSION=$(grep 'ARG PARALLELCLUSTER_VERSION=' Dockerfile | cut -d'=' -f2)
echo "version=${PARALLELCLUSTER_VERSION}" >> $GITHUB_OUTPUT
- name: Docker meta
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ steps.login-ecr.outputs.registry }}/${{ env.REPOSITORY }}
tags: |
type=sha,format=short,prefix=v${{ steps.extract_version.outputs.version }}-,suffix=-${{ matrix.platform }}
- name: Build and Push
uses: docker/build-push-action@v5
with:
context: .
push: true
platforms: ${{ matrix.platform }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
実行結果
同リポジトリ内に arm64 と amd64 用のイメージが保存されます。
今後の改善点
arm64 用ビルドに時間がかかります。
QEMU を利用しているため、arm64 イメージのビルドに約 3 倍の時間がかかっています。
GitHub Enterprise のラージランナーが利用可能な場合、Arm64 ランナーを使用することでビルド時間を短縮できるはずです。機会があった使いたいものです。
おわりに
Cloud 9 の新規利用が不可能になったことを契機に新たなpcluster
の実行環境の構築先を検討していました。この機会に、日頃感じていた不便さも解消してみようかと試してみました。試してみたあとの感想としてはイメージのプルを考慮すると、プライベート ECR ではなく認証不要のパブリックリポジトリの使用も検討の余地があると気づきました。ローカル環境で実行の際にイメージをプルすために ECR の認証をするのが煩わしいです。